import { Injectable } from '@angular/core';
import { DomService,DgControl,FormBasicService } from '@farris/designer-services';
import { ControlTreeNode, ControlTreeNodeType } from '../entity/tree-node';
import { TreeNodeMergeRuleService } from './merge-rule.service';
import { ControlTreeNodeBuilderService } from './tree-node-builder.service';

@Injectable()
export class CollapsedControlTreeBuilderService {

    private mergeService: TreeNodeMergeRuleService;
    private nodeBuilderService: ControlTreeNodeBuilderService;

    /** 平铺的完整的控件树数据，用来替换被克隆的rawElement */
    plainCompleteControlTreeNodes: ControlTreeNode[];

    constructor(
        private domService: DomService,
        private formbasicService: FormBasicService) {
        this.mergeService = new TreeNodeMergeRuleService(domService);
        this.nodeBuilderService = new ControlTreeNodeBuilderService(domService);
    }

    /**
     * 表单对象映射为树结构
     * @param formData 表单Dg对象
     */
    public mappingFormDataToTree(domJson: any): ControlTreeNode[] {
        if (!domJson) {
            return;
        }
        // 表单顶层节点
        const frameId = this.formbasicService.formMetaBasicInfo.id;
        const frameNode: ControlTreeNode = {
            data: {
                id: frameId,
                name: '页面',
            },
            rawElement: domJson,
            type: ControlTreeNodeType.Frame,
            children: [],
            expanded: true,
            index: 0,
            parentNodeId: null,
            hideContextMenuIcon: true,
            controlIcon: 'fd-i-Family fd_pc-Module',

        };
        if (this.formbasicService.envType === 'mobileDesigner') {
            const pageComponents = domJson.module.components.filter(component => component.type === 'Component' && component.componentType === 'Page');
            const pageComponentNodes = pageComponents.map(component => this.createComponentNode(component, 0, null));
            frameNode.children = pageComponentNodes;
            frameNode.data.name = domJson.module.name
            return [frameNode];
        }
        const rootComponent = domJson.module.components[0];
        const rootComponentNode = this.createComponentNode(rootComponent, 0, null);
        frameNode.children = [rootComponentNode];

        return [frameNode];
    }

    private recursionElements(parentElement: any): ControlTreeNode[] {
        const elements = parentElement.contents as any[];
        const parentNodeId = parentElement.id;

        const newComponentNodeList: ControlTreeNode[] = [];

        elements.forEach((element: any, index: number) => {
            let newComponentNode: ControlTreeNode;
            let nodeRefObject;

            if (element.type === 'ComponentRef') {
                const childComponentNode = this.domService.getComponentById(element.component);
                newComponentNode = this.createComponentNode(childComponentNode, index, parentElement);
                newComponentNodeList.push(newComponentNode);
            } else {
                const mergedEle = this.mergeService.getMergeNode(element, parentElement);
                // 获取树节点名称
                const nodeName = this.nodeBuilderService.getNodeName(element, parentElement);
                const completeNode = this.plainCompleteControlTreeNodes.find(n => n.data.id === element.id);
                newComponentNode = {
                    data: {
                        id: element.id,
                        name: nodeName,
                    },
                    rawElement: completeNode.rawElement,
                    children: [],
                    expanded: true,
                    type: ControlTreeNodeType.Control,
                    index,
                    parentNodeId,
                    rawParentNodeId: completeNode.parentNodeId,
                    controlIcon: this.nodeBuilderService.getControlIconClass(element),
                    dependentParentControl: DgControl[element.type] && DgControl[element.type].dependentParentControl
                };
                if (mergedEle) {
                    nodeRefObject = this.recursionElements(mergedEle);
                    if (nodeRefObject.length) {
                        newComponentNode.children = nodeRefObject;
                    }
                } else if (element.contents) {
                    nodeRefObject = this.recursionElements(element);
                    if (nodeRefObject.length) {
                        newComponentNode.children = nodeRefObject;
                    }
                }

                newComponentNodeList.push(newComponentNode);

                // 列表弹出编辑
                if ((DgControl.DataGrid && DgControl.DataGrid.type === element.type) && element.enableEditByCard !== 'none' && element.modalComponentId) {
                    const modalCmp = this.domService.getComponentById(element.modalComponentId);
                    if (modalCmp) {
                        const modalComponentNode = this.createComponentNode(modalCmp, index, parentElement);
                        newComponentNodeList.push(modalComponentNode);
                    }

                }

            }
        });

        return newComponentNodeList;


    }

    private createComponentNode(element: any, elementIndex: number, parentElement: any): ControlTreeNode {
        const parentNodeId = parentElement ? parentElement.id : null;

        const mergedEle = this.mergeService.getMergeNode(element, parentElement);

        // 组件子控件节点，默认为空数组。
        let controlsNodes: ControlTreeNode[] = [];
        if (mergedEle) {
            controlsNodes = this.recursionElements(mergedEle);
        } else if (element.contents) {
            controlsNodes = this.recursionElements(element);
        }


        // 获取树节点名称
        const nodeName = this.nodeBuilderService.getNodeName(element);

        // 构造组件节点
        const completeNode = this.plainCompleteControlTreeNodes.find(n => n.data.id === element.id);
        const newComponentNode: ControlTreeNode = {
            data: {
                id: element.id,
                name: nodeName,
            },
            rawElement: completeNode ? completeNode.rawElement : element,
            children: controlsNodes,
            expanded: true,
            type: ControlTreeNodeType.Component,
            index: elementIndex,
            parentNodeId,
            rawParentNodeId: completeNode ? completeNode.parentNodeId : null,
            controlIcon: this.nodeBuilderService.getControlIconClass(element)
        };
        return newComponentNode;
    }

}
